home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume19 / dmake / part27 < prev    next >
Encoding:
Text File  |  1991-05-12  |  40.1 KB  |  1,437 lines

  1. Newsgroups: comp.sources.misc
  2. From: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  3. Subject:  v19i048:  dmake - dmake version 3.7, Part27/37
  4. Message-ID: <1991May12.221544.16521@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 453cc392a39daffdc420fc8b6292518e
  6. Date: Sun, 12 May 1991 22:15:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
  10. Posting-number: Volume 19, Issue 48
  11. Archive-name: dmake/part27
  12. Supersedes: dmake-3.6: Volume 15, Issue 52-77
  13.  
  14. ---- Cut Here and feed the following to sh ----
  15. #!/bin/sh
  16. # this is dmake.shar.27 (part 27 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file dmake/os2/mscdos/public.h continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 27; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test -f _shar_wnt_.tmp; then
  33. sed 's/^X//' << 'SHAR_EOF' >> 'dmake/os2/mscdos/public.h' &&
  34. void Catch_signals ANSI((void (*)()));
  35. void Clear_signals ANSI(());
  36. void Prolog ANSI((int, char* []));
  37. void Epilog ANSI((int));
  38. char * Get_current_dir ANSI(());
  39. int Set_dir ANSI((char*));
  40. char Get_switch_char ANSI(());
  41. FILE* Get_temp ANSI((char **, char *, int));
  42. FILE * Start_temp ANSI((char *, CELLPTR, char **));
  43. void Open_temp_error ANSI((char *, char *));
  44. void Link_temp ANSI((CELLPTR, FILE *, char *));
  45. void Close_temp ANSI((CELLPTR, FILE *));
  46. void Unlink_temp_files ANSI((CELLPTR));
  47. void Handle_result ANSI((int, int, int, CELLPTR));
  48. void Update_time_stamp ANSI((CELLPTR));
  49. void Parse ANSI((FILE *));
  50. int Get_line ANSI((char *, FILE *));
  51. char * Do_comment ANSI((char *, char **, int));
  52. char * Get_token ANSI((TKSTRPTR, char *, int));
  53. void Quit ANSI(());
  54. void Read_state ANSI(());
  55. void Write_state ANSI(());
  56. int Check_state ANSI((CELLPTR, STRINGPTR *, int));
  57. char* basename ANSI((char *));
  58. void Dump ANSI(());
  59. void Dump_recipe ANSI((STRINGPTR));
  60. int Parse_macro ANSI((char *, int));
  61. int Macro_op ANSI((char *));
  62. int Parse_rule_def ANSI((int *));
  63. int Rule_op ANSI((char *));
  64. void Add_recipe_to_list ANSI((char *, int, int));
  65. void Bind_rules_to_targets ANSI((int));
  66. int Set_group_attributes ANSI((char *));
  67. DFALINKPTR Match_dfa ANSI((char *));
  68. void Check_circle_dfa ANSI(());
  69. void Add_nfa ANSI((char *));
  70. char * Exec_function ANSI((char *));
  71. int runargv ANSI((CELLPTR, int, int, int, int, char *));
  72. void SetSessionTitle ANSI(());
  73. int Wait_for_child ANSI((int, int));
  74. void Clean_up_processes ANSI(());
  75. int _chdir ANSI((char *));
  76. int If_root_path ANSI((char *));
  77. time_t seek_arch ANSI((char*, char*));
  78. int touch_arch ANSI((char*, char*));
  79. void Remove_prq ANSI((CELLPTR));
  80. X
  81. #endif
  82. SHAR_EOF
  83. chmod 0640 dmake/os2/mscdos/public.h ||
  84. echo 'restore of dmake/os2/mscdos/public.h failed'
  85. Wc_c="`wc -c < 'dmake/os2/mscdos/public.h'`"
  86. test 5614 -eq "$Wc_c" ||
  87.     echo 'dmake/os2/mscdos/public.h: original size 5614, current size' "$Wc_c"
  88. rm -f _shar_wnt_.tmp
  89. fi
  90. # ============= dmake/os2/mscdos/startup.mk ==============
  91. if test -f 'dmake/os2/mscdos/startup.mk' -a X"$1" != X"-c"; then
  92.     echo 'x - skipping dmake/os2/mscdos/startup.mk (File already exists)'
  93.     rm -f _shar_wnt_.tmp
  94. else
  95. > _shar_wnt_.tmp
  96. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/mscdos/startup.mk' &&
  97. #NOTE:  startup.mk file is called dmake.ini for OS/2
  98. #       and is found in os2/mscdos/dmake.ini
  99. .INCLUDE : "os2/mscdos/dmake.ini"
  100. SHAR_EOF
  101. chmod 0640 dmake/os2/mscdos/startup.mk ||
  102. echo 'restore of dmake/os2/mscdos/startup.mk failed'
  103. Wc_c="`wc -c < 'dmake/os2/mscdos/startup.mk'`"
  104. test 132 -eq "$Wc_c" ||
  105.     echo 'dmake/os2/mscdos/startup.mk: original size 132, current size' "$Wc_c"
  106. rm -f _shar_wnt_.tmp
  107. fi
  108. # ============= dmake/os2/mscdos/tempnam.c ==============
  109. if test -f 'dmake/os2/mscdos/tempnam.c' -a X"$1" != X"-c"; then
  110.     echo 'x - skipping dmake/os2/mscdos/tempnam.c (File already exists)'
  111.     rm -f _shar_wnt_.tmp
  112. else
  113. > _shar_wnt_.tmp
  114. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/mscdos/tempnam.c' &&
  115. /*LINTLIBRARY*/
  116. #include <stdio.h>
  117. #include <string.h>
  118. #include <stdlib.h>
  119. #include <dos.h>
  120. X
  121. #if defined(max)
  122. #   undef  max
  123. #endif
  124. #define max(A,B) (((A)<(B))?(B):(A))
  125. X
  126. extern int access();
  127. int _access();
  128. X
  129. /* MSC stdio.h defines P_tmpdir, so let's undo it here */
  130. /* Under DOS leave the default tmpdir pointing here!        */
  131. #ifdef P_tmpdir
  132. #undef P_tmpdir
  133. #endif
  134. static char *P_tmpdir = "";
  135. X
  136. char *
  137. tempnam(dir, prefix)
  138. char *dir;        /* use this directory please (if non-NULL) */
  139. char *prefix;        /* use this (if non-NULL) as filename prefix */
  140. {
  141. X   static         int count = 0;
  142. X   register char *p, *q, *tmpdir;
  143. X   int            tl=0, dl=0, pl;
  144. X   char          buf[30];
  145. X
  146. X   pl = strlen(P_tmpdir);
  147. X
  148. X   if( (tmpdir = getenv("TMPDIR")) != NULL )
  149. X      tl = strlen(tmpdir);
  150. X   else if( (tmpdir = getenv("TMP")) != NULL )
  151. X      tl = strlen(tmpdir);
  152. X   if( dir != NULL ) dl = strlen(dir);
  153. X
  154. X   if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL )
  155. X     return(NULL);
  156. X
  157. X   *p = '\0';
  158. X
  159. X   if( (tl == 0) || (_access( strcpy(p, tmpdir), 0) != 0) )
  160. X     if( (dl == 0) || (_access( strcpy(p, dir), 0) != 0) )
  161. X    if( _access( strcpy(p, P_tmpdir), 0) != 0 )
  162. X       if( !prefix )
  163. X          prefix = "tp";
  164. X
  165. X   if(prefix)
  166. X   {
  167. X      *(p+strlen(p)+2) = '\0';
  168. X      (void)strncat(p, prefix, 2);
  169. X   }
  170. X
  171. #ifdef OS2
  172. X   sprintf( buf, "%08x", getpid() );
  173. #else
  174. X   sprintf( buf, "%08x", _psp );
  175. #endif
  176. X   buf[6]='\0';
  177. X   (void)strcat(p, buf );
  178. X   sprintf( buf, "%04d", count++ );
  179. X   q=p+strlen(p)-6;
  180. X   *q++ = buf[0]; *q++ = buf[1];
  181. X   *q++ = buf[2]; *q++ = buf[3];
  182. X
  183. X   if( (q = strrchr(p,'.')) != NULL ) *q = '\0';
  184. X
  185. X   return strlwr(p);
  186. }
  187. X
  188. X
  189. X
  190. _access( name, flag )
  191. char *name;
  192. int  flag;
  193. {
  194. X   char *p;
  195. X   int r;
  196. X
  197. X   if( name == NULL || !*name ) return(1);  /* NULL dir means current dir */
  198. X   p = name+strlen(name)-1;
  199. X   if(*p == ':' ) strcat( p++, "\\" );
  200. X   r = access( name, flag );
  201. X   if(*p != '/' && *p != '\\') strcat( p, "\\" );
  202. X
  203. X   return( r );
  204. }
  205. SHAR_EOF
  206. chmod 0640 dmake/os2/mscdos/tempnam.c ||
  207. echo 'restore of dmake/os2/mscdos/tempnam.c failed'
  208. Wc_c="`wc -c < 'dmake/os2/mscdos/tempnam.c'`"
  209. test 1919 -eq "$Wc_c" ||
  210.     echo 'dmake/os2/mscdos/tempnam.c: original size 1919, current size' "$Wc_c"
  211. rm -f _shar_wnt_.tmp
  212. fi
  213. # ============= dmake/os2/ruletab.c ==============
  214. if test -f 'dmake/os2/ruletab.c' -a X"$1" != X"-c"; then
  215.     echo 'x - skipping dmake/os2/ruletab.c (File already exists)'
  216.     rm -f _shar_wnt_.tmp
  217. else
  218. > _shar_wnt_.tmp
  219. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/ruletab.c' &&
  220. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/os2/RCS/ruletab.c,v 1.1 91/05/06 15:33:22 dvadura Exp $
  221. -- SYNOPSIS -- Default initial configuration of dmake.
  222. -- 
  223. -- DESCRIPTION
  224. --     Define here the initial set of rules that are defined before
  225. --    dmake performs any processing.
  226. --
  227. -- AUTHOR
  228. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  229. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  230. --
  231. -- COPYRIGHT
  232. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  233. -- 
  234. --      This program is free software; you can redistribute it and/or
  235. --      modify it under the terms of the GNU General Public License
  236. --      (version 1), as published by the Free Software Foundation, and
  237. --      found in the file 'LICENSE' included with this distribution.
  238. -- 
  239. --      This program is distributed in the hope that it will be useful,
  240. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  241. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  242. --      GNU General Public License for more details.
  243. -- 
  244. --      You should have received a copy of the GNU General Public License
  245. --      along with this program;  if not, write to the Free Software
  246. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  247. --
  248. -- LOG
  249. --     $Log:    ruletab.c,v $
  250. X * Revision 1.1  91/05/06  15:33:22  dvadura
  251. X * dmake Release Version 3.7
  252. X * 
  253. */
  254. X
  255. /* These are control macros for dmake that MUST be defined at some point
  256. X * if they are NOT dmake will not work!  These are default definitions.  They
  257. X * may be overridden inside the .STARTUP makefile, they are here
  258. X * strictly so that dmake can parse the STARTUP makefile */
  259. /*
  260. X * For OS/2 these are close to the Unix definitions in terms of limits.
  261. X * We dont need the two different cases of Makefile, so only keep the
  262. X * pretty one.
  263. X */
  264. static char *_rules[] = {
  265. X    "MAXLINELENGTH := 2046",
  266. X    "MAXPROCESSLIMIT := 16",
  267. X    ".IMPORT .IGNORE: ROOTDIR INIT",
  268. X    ".MAKEFILES : makefile.mk Makefile",
  269. X    ".SOURCE    : .NULL",
  270. #include "startup.h"
  271. X    0 };
  272. X
  273. char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */
  274. X
  275. SHAR_EOF
  276. chmod 0640 dmake/os2/ruletab.c ||
  277. echo 'restore of dmake/os2/ruletab.c failed'
  278. Wc_c="`wc -c < 'dmake/os2/ruletab.c'`"
  279. test 2098 -eq "$Wc_c" ||
  280.     echo 'dmake/os2/ruletab.c: original size 2098, current size' "$Wc_c"
  281. rm -f _shar_wnt_.tmp
  282. fi
  283. # ============= dmake/os2/runargv.c ==============
  284. if test -f 'dmake/os2/runargv.c' -a X"$1" != X"-c"; then
  285.     echo 'x - skipping dmake/os2/runargv.c (File already exists)'
  286.     rm -f _shar_wnt_.tmp
  287. else
  288. > _shar_wnt_.tmp
  289. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/runargv.c' &&
  290. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/os2/RCS/runargv.c,v 1.1 91/05/06 15:33:22 dvadura Exp $
  291. -- SYNOPSIS -- invoke a sub process, modified unix/runargv.c for OS/2.
  292. -- 
  293. -- DESCRIPTION
  294. --     Use the standard methods of executing a sub process.
  295. --
  296. -- AUTHOR
  297. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  298. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  299. --
  300. -- COPYRIGHT
  301. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  302. -- 
  303. --      This program is free software; you can redistribute it and/or
  304. --      modify it under the terms of the GNU General Public License
  305. --      (version 1), as published by the Free Software Foundation, and
  306. --      found in the file 'LICENSE' included with this distribution.
  307. -- 
  308. --      This program is distributed in the hope that it will be useful,
  309. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  310. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  311. --      GNU General Public License for more details.
  312. -- 
  313. --      You should have received a copy of the GNU General Public License
  314. --      along with this program;  if not, write to the Free Software
  315. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  316. --
  317. -- LOG
  318. --     $Log:    runargv.c,v $
  319. X * Revision 1.1  91/05/06  15:33:22  dvadura
  320. X * dmake Release Version 3.7
  321. X * 
  322. */
  323. X
  324. #define INCL_DOSPROCESS
  325. #include <os2.h>
  326. X
  327. #include <process.h>
  328. #include <stdlib.h>
  329. #include <signal.h>
  330. #include "extern.h"
  331. #include "sysintf.h"
  332. X
  333. typedef struct prp {
  334. X   char *prp_cmd;
  335. X   int   prp_group;
  336. X   int   prp_ignore;
  337. X   int   prp_last;
  338. X   int     prp_shell;
  339. X   struct prp *prp_next;
  340. } RCP, *RCPPTR;
  341. X
  342. typedef struct pr {
  343. X   int        pr_valid;
  344. X   int        pr_pid;
  345. X   CELLPTR    pr_target;
  346. X   int        pr_ignore;
  347. X   int        pr_last;
  348. X   RCPPTR      pr_recipe;
  349. X   RCPPTR      pr_recipe_end;
  350. X   char        *pr_dir;
  351. } PR;
  352. X
  353. static PR  *_procs    = NIL(PR);
  354. static int  _proc_cnt = 0;
  355. static int  _abort_flg= FALSE;
  356. static int  _use_i    = -1;
  357. static int  _do_upd   = 0;
  358. X
  359. extern unsigned int _far _pascal DosSmSetTitle(char _far *s);
  360. static  void    SetSessionTitle (char *s);
  361. static  void    _add_child ANSI((int, CELLPTR, int, int));
  362. static  void    _attach_cmd ANSI((char *, int, int, CELLPTR, int, int));
  363. static  void    _finished_child ANSI((int, int));
  364. static  int     _running ANSI((CELLPTR));
  365. X
  366. PUBLIC int
  367. runargv(target, ignore, group, last, shell, cmd)
  368. CELLPTR target;
  369. int     ignore;
  370. int    group;
  371. int    last;
  372. int     shell;
  373. char    *cmd;
  374. {
  375. X   int          pid;
  376. X   char         **argv;
  377. X
  378. X   if( _running(target) /*&& Max_proc != 1*/ ) {
  379. X      /* The command will be executed when the previous recipe
  380. X       * line completes. */
  381. X      _attach_cmd( cmd, group, ignore, target, last, shell );
  382. X      return(1);
  383. X   }
  384. X
  385. X   while( _proc_cnt == Max_proc )
  386. X      if( Wait_for_child(FALSE, -1) == -1 )  Fatal( "Lost a child" );
  387. X
  388. #ifdef SESSTITLE
  389. X   SetSessionTitle(target->CE_NAME);
  390. #endif
  391. X   argv = Pack_argv( group, shell, cmd );
  392. X
  393. X   if((pid=spawnvp((_osmode == DOS_MODE)?P_WAIT:P_NOWAIT,argv[0],argv)) == -1){
  394. X      Error("%s: %s", argv[0], sys_errlist[errno]);
  395. X      Handle_result(-1, ignore, _abort_flg, target);
  396. X      return(-1);
  397. X   }
  398. X   else if( _osmode == DOS_MODE ) {
  399. X     _add_child(4711, target, ignore, last);
  400. X     _finished_child(4711, pid);
  401. X   }
  402. X   else
  403. X     _add_child(pid, target, ignore, last);
  404. X
  405. X   return(1);
  406. }
  407. X
  408. X
  409. #ifdef SESSTITLE
  410. /* N.B. The system call used below is undocumented and therefore possibly
  411. X * subject to change. It sets the session title even from a full screen
  412. X * session, so you can see which target is being built.
  413. X * If dubious about undocumented calls simply remove it.
  414. X */
  415. PUBLIC void
  416. SetSessionTitle(char *s)
  417. {
  418. X   char buff[128];
  419. X   strncpy(buff, Pname, sizeof(buff));
  420. X   buff[sizeof(buff)-1] = 0;
  421. X   strncat(buff, " - ", sizeof(buff));
  422. X   strncat(buff, s, sizeof(buff));
  423. X   buff[sizeof(buff)-1] = 0;
  424. X   DosSmSetTitle(buff);
  425. }
  426. #endif
  427. X
  428. X
  429. PUBLIC int
  430. Wait_for_child( abort_flg, pid )
  431. int abort_flg;
  432. int pid;
  433. {
  434. X   int wid;
  435. X   int status;
  436. X   int waitchild;
  437. X
  438. X   if( _osmode == DOS_MODE ) return(1);
  439. X
  440. X   waitchild = (pid == -1)? FALSE : Wait_for_completion;
  441. X
  442. X   do {
  443. X      if( (wid = wait(&status)) == -1 ) return(-1);
  444. X
  445. X      _abort_flg = abort_flg;
  446. X      _finished_child(wid, status);
  447. X      _abort_flg = FALSE;
  448. X   }
  449. X   while( waitchild && pid != wid );
  450. X
  451. X   return(0);
  452. }
  453. X
  454. X
  455. PUBLIC void
  456. Clean_up_processes()
  457. {
  458. X   register int i;
  459. X
  460. X   if( _osmode == DOS_MODE ) {
  461. X      _abort_flg = TRUE;
  462. X      _finished_child(4711, -1);
  463. X      return;
  464. X   }
  465. X
  466. X   if( _procs != NIL(PR) ) {
  467. X      for( i=0; i<Max_proc; i++ )
  468. X     if( _procs[i].pr_valid )
  469. X        DosKillProcess(DKP_PROCESSTREE, _procs[i].pr_pid);
  470. X
  471. X      while( Wait_for_child(TRUE, -1) != -1 );
  472. X   }
  473. }
  474. X
  475. X
  476. static void
  477. _add_child( pid, target, ignore, last )
  478. int    pid;
  479. CELLPTR target;
  480. int    ignore;
  481. int     last;
  482. {
  483. X   register int i;
  484. X   register PR *pp;
  485. X
  486. X   if( _procs == NIL(PR) ) {
  487. X      TALLOC( _procs, Max_proc, PR );
  488. X   }
  489. X
  490. X   if( (i = _use_i) == -1 )
  491. X      for( i=0; i<Max_proc; i++ )
  492. X     if( !_procs[i].pr_valid )
  493. X        break;
  494. X
  495. X   pp = _procs+i;
  496. X
  497. X   pp->pr_valid  = 1;
  498. X   pp->pr_pid    = pid;
  499. X   pp->pr_target = target;
  500. X   pp->pr_ignore = ignore;
  501. X   pp->pr_last   = last;
  502. X   pp->pr_dir    = _strdup(Get_current_dir());
  503. X
  504. X   Current_target = NIL(CELL);
  505. X
  506. X   _proc_cnt++;
  507. X
  508. X   if( Wait_for_completion ) Wait_for_child( FALSE, pid );
  509. }
  510. X
  511. X
  512. static void
  513. _finished_child(pid, status)
  514. int    pid;
  515. int    status;
  516. {
  517. X   register int i;
  518. X   register PR *pp;
  519. X   char     *dir;
  520. X
  521. X   for( i=0; i<Max_proc; i++ )
  522. X      if( _procs[i].pr_valid && _procs[i].pr_pid == pid )
  523. X     break;
  524. X
  525. X   /* Some children we didn't make esp true if using /bin/sh to execute a
  526. X    * a pipe and feed the output as a makefile into dmake. */
  527. X   if( i == Max_proc ) return;
  528. X   _procs[i].pr_valid = 0;
  529. X   _proc_cnt--;
  530. X   dir = _strdup(Get_current_dir());
  531. X   Set_dir( _procs[i].pr_dir );
  532. X
  533. X   if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) {
  534. X      RCPPTR rp = _procs[i].pr_recipe;
  535. X
  536. X
  537. X      Current_target = _procs[i].pr_target;
  538. X      Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target );
  539. X      Current_target = NIL(CELL);
  540. X
  541. X      _procs[i].pr_recipe = rp->prp_next;
  542. X
  543. X      _use_i = i;
  544. X      runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group,
  545. X           rp->prp_last, rp->prp_shell, rp->prp_cmd );
  546. X      _use_i = -1;
  547. X
  548. X      FREE( rp->prp_cmd );
  549. X      FREE( rp );
  550. X
  551. X      if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
  552. X   }
  553. X   else {
  554. X      Unlink_temp_files( _procs[i].pr_target );
  555. X      Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target);
  556. X
  557. X      if( _procs[i].pr_last ) {
  558. X     FREE(_procs[i].pr_dir );
  559. X
  560. X     if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target );
  561. X      }
  562. X   }
  563. X
  564. X   Set_dir(dir);
  565. X   FREE(dir);
  566. }
  567. X
  568. X
  569. static int
  570. _running( cp )
  571. CELLPTR cp;
  572. {
  573. X   register int i;
  574. X
  575. X   if( !_procs ) return(FALSE);
  576. X
  577. X   for( i=0; i<Max_proc; i++ )
  578. X      if( _procs[i].pr_valid &&
  579. X      _procs[i].pr_target == cp  )
  580. X     break;
  581. X     
  582. X   return( i != Max_proc );
  583. }
  584. X
  585. X
  586. static void
  587. _attach_cmd( cmd, group, ignore, cp, last, shell )
  588. char    *cmd;
  589. int    group;
  590. int     ignore;
  591. CELLPTR cp;
  592. int     last;
  593. int     shell;
  594. {
  595. X   register int i;
  596. X   RCPPTR rp;
  597. X
  598. X   for( i=0; i<Max_proc; i++ )
  599. X      if( _procs[i].pr_valid &&
  600. X      _procs[i].pr_target == cp  )
  601. X     break;
  602. X
  603. X   TALLOC( rp, 1, RCP );
  604. X   rp->prp_cmd   = _strdup(cmd);
  605. X   rp->prp_group = group;
  606. X   rp->prp_ignore= ignore;
  607. X   rp->prp_last  = last;
  608. X   rp->prp_shell = shell;
  609. X   rp->prp_dir   = _strdup(Get_current_dir());
  610. X
  611. X   if( _procs[i].pr_recipe == NIL(RCP) )
  612. X      _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp;
  613. X   else {
  614. X      _procs[i].pr_recipe_end->prp_next = rp;
  615. X      _procs[i].pr_recipe_end = rp;
  616. X   }
  617. }
  618. SHAR_EOF
  619. chmod 0640 dmake/os2/runargv.c ||
  620. echo 'restore of dmake/os2/runargv.c failed'
  621. Wc_c="`wc -c < 'dmake/os2/runargv.c'`"
  622. test 7611 -eq "$Wc_c" ||
  623.     echo 'dmake/os2/runargv.c: original size 7611, current size' "$Wc_c"
  624. rm -f _shar_wnt_.tmp
  625. fi
  626. # ============= dmake/os2/startup.h ==============
  627. if test -f 'dmake/os2/startup.h' -a X"$1" != X"-c"; then
  628.     echo 'x - skipping dmake/os2/startup.h (File already exists)'
  629.     rm -f _shar_wnt_.tmp
  630. else
  631. > _shar_wnt_.tmp
  632. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/startup.h' &&
  633. /* This file contains the default value of the MAKESTARTUP variable.
  634. X * You must set the quoted string below to the default path to the startup
  635. X * variable, so that it gets compiled in.  LEAVE ROOTDIR at the front of
  636. X * the path.  This allows the user to customize his environment for dmake
  637. X * by setting up a new ROOTDIR environment variable. */
  638. X
  639. "MAKESTARTUP := $(INIT)/dmake.ini",
  640. SHAR_EOF
  641. chmod 0640 dmake/os2/startup.h ||
  642. echo 'restore of dmake/os2/startup.h failed'
  643. Wc_c="`wc -c < 'dmake/os2/startup.h'`"
  644. test 384 -eq "$Wc_c" ||
  645.     echo 'dmake/os2/startup.h: original size 384, current size' "$Wc_c"
  646. rm -f _shar_wnt_.tmp
  647. fi
  648. # ============= dmake/os2/stdarg.h ==============
  649. if test -f 'dmake/os2/stdarg.h' -a X"$1" != X"-c"; then
  650.     echo 'x - skipping dmake/os2/stdarg.h (File already exists)'
  651.     rm -f _shar_wnt_.tmp
  652. else
  653. > _shar_wnt_.tmp
  654. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/stdarg.h' &&
  655. /*
  656. X * stdarg.h
  657. X *
  658. X * defines ANSI style macros for accessing arguments of a function which takes
  659. X * a variable number of arguments
  660. X *
  661. X */
  662. X
  663. #if !defined(__STDARG)
  664. #define __STDARG
  665. X
  666. typedef char *va_list;
  667. X
  668. #define va_dcl int va_alist
  669. #define va_start(ap,v)  ap = (va_list)&va_alist
  670. #define va_arg(ap,t)    ((t*)(ap += sizeof(t)))[-1]
  671. #define va_end(ap)      ap = NULL
  672. #endif
  673. SHAR_EOF
  674. chmod 0640 dmake/os2/stdarg.h ||
  675. echo 'restore of dmake/os2/stdarg.h failed'
  676. Wc_c="`wc -c < 'dmake/os2/stdarg.h'`"
  677. test 373 -eq "$Wc_c" ||
  678.     echo 'dmake/os2/stdarg.h: original size 373, current size' "$Wc_c"
  679. rm -f _shar_wnt_.tmp
  680. fi
  681. # ============= dmake/os2/switchar.c ==============
  682. if test -f 'dmake/os2/switchar.c' -a X"$1" != X"-c"; then
  683.     echo 'x - skipping dmake/os2/switchar.c (File already exists)'
  684.     rm -f _shar_wnt_.tmp
  685. else
  686. > _shar_wnt_.tmp
  687. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/switchar.c' &&
  688. /*
  689. ** return switch char
  690. */
  691. #if defined(OS2) || defined(_MSC_VER)
  692. #include <stdlib.h>
  693. #endif
  694. #if !defined(OS2)
  695. #include <dos.h>
  696. #endif /* !OS2 */
  697. #include <stdio.h>
  698. #include "stdmacs.h"
  699. X
  700. getswitchar()/*
  701. ===============
  702. X   Try the environment first.  If you don't find SWITCHAR there, then use
  703. X   the DOS call.  The call is undocumented, and doesn't work for DOS versions
  704. X   4.0 and up, so the check of the environment will fix that. */
  705. {
  706. #if defined(M_I86)
  707. #if !defined(OS2)
  708. X   union REGS rg;
  709. #endif /* ! OS2 */
  710. X   static char *_env_switchar = NIL(char);
  711. X
  712. X   if( _env_switchar != NIL(char) ||
  713. X       (_env_switchar = (char *)getenv("SWITCHAR")) != NIL(char) )
  714. X      return(*_env_switchar);
  715. X
  716. #if !defined(OS2)
  717. X   rg.h.ah = 0x37;      /* switch char request */
  718. X   rg.h.al = 0;         /* get (not set) */
  719. X
  720. X   intdos(&rg, &rg);
  721. X   return (rg.h.dl);
  722. #endif /* ! OS2 */
  723. #endif /* M_I86 */
  724. X
  725. X   return ('/');
  726. }
  727. SHAR_EOF
  728. chmod 0640 dmake/os2/switchar.c ||
  729. echo 'restore of dmake/os2/switchar.c failed'
  730. Wc_c="`wc -c < 'dmake/os2/switchar.c'`"
  731. test 904 -eq "$Wc_c" ||
  732.     echo 'dmake/os2/switchar.c: original size 904, current size' "$Wc_c"
  733. rm -f _shar_wnt_.tmp
  734. fi
  735. # ============= dmake/os2/sysintf.h ==============
  736. if test -f 'dmake/os2/sysintf.h' -a X"$1" != X"-c"; then
  737.     echo 'x - skipping dmake/os2/sysintf.h (File already exists)'
  738.     rm -f _shar_wnt_.tmp
  739. else
  740. > _shar_wnt_.tmp
  741. sed 's/^X//' << 'SHAR_EOF' > 'dmake/os2/sysintf.h' &&
  742. /*
  743. ** assorted bits of system interface
  744. */
  745. X
  746. #define STAT stat
  747. #define VOID_LCACHE(l,m)
  748. #define Hook_std_writes(A)
  749. #define GETPID getpid()
  750. X
  751. extern char * tempnam();
  752. extern char * getcwd();
  753. X
  754. /*
  755. ** standard C items
  756. */
  757. X
  758. /*
  759. ** DOS interface standard items
  760. */
  761. #define    chdir(p) _chdir(p)
  762. X
  763. /*
  764. ** make parameters
  765. */
  766. #define    MAX_PATH_LEN    256
  767. X
  768. SHAR_EOF
  769. chmod 0640 dmake/os2/sysintf.h ||
  770. echo 'restore of dmake/os2/sysintf.h failed'
  771. Wc_c="`wc -c < 'dmake/os2/sysintf.h'`"
  772. test 333 -eq "$Wc_c" ||
  773.     echo 'dmake/os2/sysintf.h: original size 333, current size' "$Wc_c"
  774. rm -f _shar_wnt_.tmp
  775. fi
  776. # ============= dmake/parse.c ==============
  777. if test -f 'dmake/parse.c' -a X"$1" != X"-c"; then
  778.     echo 'x - skipping dmake/parse.c (File already exists)'
  779.     rm -f _shar_wnt_.tmp
  780. else
  781. > _shar_wnt_.tmp
  782. sed 's/^X//' << 'SHAR_EOF' > 'dmake/parse.c' &&
  783. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/parse.c,v 1.1 91/05/06 15:23:20 dvadura Exp $
  784. -- SYNOPSIS -- parse the input, and perform semantic analysis
  785. -- 
  786. -- DESCRIPTION
  787. --     This file contains the routines that parse the input makefile and
  788. --    call the appropriate routines to perform the semantic analysis and
  789. --    build the internal dag.
  790. --
  791. -- AUTHOR
  792. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  793. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  794. --
  795. -- COPYRIGHT
  796. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  797. -- 
  798. --      This program is free software; you can redistribute it and/or
  799. --      modify it under the terms of the GNU General Public License
  800. --      (version 1), as published by the Free Software Foundation, and
  801. --      found in the file 'LICENSE' included with this distribution.
  802. -- 
  803. --      This program is distributed in the hope that it will be useful,
  804. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  805. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  806. --      GNU General Public License for more details.
  807. -- 
  808. --      You should have received a copy of the GNU General Public License
  809. --      along with this program;  if not, write to the Free Software
  810. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  811. --
  812. -- LOG
  813. --     $Log:    parse.c,v $
  814. X * Revision 1.1  91/05/06  15:23:20  dvadura
  815. X * dmake Release Version 3.7
  816. X * 
  817. */
  818. X
  819. #include "extern.h"
  820. X
  821. X
  822. PUBLIC void
  823. Parse( fil )/*
  824. ==============  Parse the makefile input */
  825. FILE *fil;
  826. {
  827. X   int  rule  = FALSE;                 /* have seen a recipe line        */
  828. X   char *p;                   /* termporary pointer into Buffer */
  829. X
  830. X   DB_ENTER( "Parse" );
  831. X
  832. X   State = NORMAL_SCAN;
  833. X   Group = FALSE;                 /* true if scanning a group rcpe  */
  834. X   while( TRUE ) {
  835. X      if( Get_line( Buffer, fil ) ) {
  836. X     if( fil != NIL( FILE ) )               /* end of parsable input */
  837. X        Closefile();
  838. X
  839. X     Bind_rules_to_targets( F_DEFAULT );
  840. X         if( Group )  Fatal( "Incomplete rule recipe group detected" );
  841. X
  842. X     DB_VOID_RETURN;
  843. X      }
  844. X      else {
  845. X         switch( State ) {
  846. X        case RULE_SCAN:
  847. X
  848. X           /* Check for the `[' that starts off a group rule definition.  It
  849. X            * must appear as the first non-white space
  850. X        * character in the line. */
  851. X
  852. X           p = _strspn( Buffer, " \t\r\n" );
  853. X               if( Set_group_attributes( p ) ) {
  854. X                  if( rule && Group )
  855. X                     Fatal( "Cannot mix single and group recipe lines" );
  856. X                  else
  857. X                     Group = TRUE;
  858. X
  859. X                  rule = TRUE;
  860. X
  861. X                  break;                     /* ignore the group start  */
  862. X               }
  863. X
  864. X               if( Group ) {
  865. X                  if( *p != ']' ) {
  866. X                     Add_recipe_to_list( Buffer, TRUE, TRUE );
  867. X                     rule = TRUE;
  868. X                  }
  869. X                  else
  870. X                     State = NORMAL_SCAN;
  871. X               }
  872. X               else {
  873. X                  if( *Buffer == '\t' ) {
  874. X                     Add_recipe_to_list( Buffer, FALSE, FALSE );
  875. X                     rule = TRUE;
  876. X                  }
  877. X                  else if( *p == ']' )
  878. X                     Fatal( "Found unmatched ']'" );
  879. X                  else if( *Buffer && *p )
  880. X             State = NORMAL_SCAN;
  881. X               }
  882. X               if( State == RULE_SCAN ) break;     /* ie. keep going    */
  883. X               
  884. X           Bind_rules_to_targets( (Group) ? F_GROUP: F_DEFAULT );
  885. X
  886. X               rule = FALSE;
  887. X               if( Group ) {
  888. X                  Group = FALSE;
  889. X                  break;
  890. X               }
  891. X           /*FALLTRHOUGH*/
  892. X
  893. X               /* In this case we broke out of the rule scan because we do not
  894. X                * have a recipe line that begins with a <TAB>, so lets
  895. X        * try to scan the thing as a macro or rule definition. */
  896. X               
  897. X
  898. X        case NORMAL_SCAN:
  899. X           if( !*Buffer ) continue;         /* we have null input line */
  900. X
  901. X           /* STUPID AUGMAKE uses "include" at the start of a line as
  902. X            * a signal to include a new file, so let's look for it.
  903. X        * if we see it replace it by .INCLUDE: and stick this back
  904. X        * into the buffer. */
  905. X           if( !strncmp( "include", Buffer, 7 ) &&
  906. X           (Buffer[7] == ' ' || Buffer[7] == '\t') )
  907. X           {
  908. X          char *tmp;
  909. X
  910. X          tmp = _strjoin( ".INCLUDE:", Buffer+7, -1, FALSE );
  911. X          strcpy( Buffer, tmp );
  912. X          FREE( tmp );
  913. X           }
  914. X
  915. X               /* look for a macro definition, they all contain an = sign
  916. X            * if we fail to recognize it as a legal macro op then try to
  917. X        * parse the same line as a rule definition, it's one or the
  918. X        * other */
  919. X        
  920. X           if( Parse_macro(Buffer, M_DEFAULT) ) break;/* it's a macro def */
  921. X           if( Parse_rule_def( &State ) )         break;/* it's a rule def  */
  922. X
  923. X           /* if just blank line then ignore it */
  924. X           if( *_strspn( Buffer, " \t\r\n" ) == '\0' ) break;
  925. X           
  926. X           /* otherwise assume it was a line of unrecognized input, or a
  927. X            * recipe line out of place so print a message */
  928. X        
  929. X           Fatal( "Expecting macro or rule defn, found neither" );
  930. X           break;
  931. X
  932. X        default:
  933. X           Fatal( "Internal -- UNKNOWN Parser state %d", State );
  934. X     }
  935. X      }
  936. X   }
  937. }
  938. X
  939. SHAR_EOF
  940. chmod 0640 dmake/parse.c ||
  941. echo 'restore of dmake/parse.c failed'
  942. Wc_c="`wc -c < 'dmake/parse.c'`"
  943. test 5207 -eq "$Wc_c" ||
  944.     echo 'dmake/parse.c: original size 5207, current size' "$Wc_c"
  945. rm -f _shar_wnt_.tmp
  946. fi
  947. # ============= dmake/patchlvl.h ==============
  948. if test -f 'dmake/patchlvl.h' -a X"$1" != X"-c"; then
  949.     echo 'x - skipping dmake/patchlvl.h (File already exists)'
  950.     rm -f _shar_wnt_.tmp
  951. else
  952. > _shar_wnt_.tmp
  953. sed 's/^X//' << 'SHAR_EOF' > 'dmake/patchlvl.h' &&
  954. /* dmake patch level, reset to 0 for each new version release. */
  955. X
  956. #define PATCHLEVEL 0
  957. SHAR_EOF
  958. chmod 0640 dmake/patchlvl.h ||
  959. echo 'restore of dmake/patchlvl.h failed'
  960. Wc_c="`wc -c < 'dmake/patchlvl.h'`"
  961. test 88 -eq "$Wc_c" ||
  962.     echo 'dmake/patchlvl.h: original size 88, current size' "$Wc_c"
  963. rm -f _shar_wnt_.tmp
  964. fi
  965. # ============= dmake/path.c ==============
  966. if test -f 'dmake/path.c' -a X"$1" != X"-c"; then
  967.     echo 'x - skipping dmake/path.c (File already exists)'
  968.     rm -f _shar_wnt_.tmp
  969. else
  970. > _shar_wnt_.tmp
  971. sed 's/^X//' << 'SHAR_EOF' > 'dmake/path.c' &&
  972. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/path.c,v 1.1 91/05/06 15:23:23 dvadura Exp $
  973. -- SYNOPSIS -- pathname manipulation code
  974. -- 
  975. -- DESCRIPTION
  976. --    Pathname routines to handle building and pulling appart
  977. --    pathnames.
  978. -- 
  979. -- AUTHOR
  980. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  981. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  982. --
  983. -- COPYRIGHT
  984. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  985. -- 
  986. --      This program is free software; you can redistribute it and/or
  987. --      modify it under the terms of the GNU General Public License
  988. --      (version 1), as published by the Free Software Foundation, and
  989. --      found in the file 'LICENSE' included with this distribution.
  990. -- 
  991. --      This program is distributed in the hope that it will be useful,
  992. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  993. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  994. --      GNU General Public License for more details.
  995. -- 
  996. --      You should have received a copy of the GNU General Public License
  997. --      along with this program;  if not, write to the Free Software
  998. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  999. --
  1000. -- LOG
  1001. --     $Log:    path.c,v $
  1002. X * Revision 1.1  91/05/06  15:23:23  dvadura
  1003. X * dmake Release Version 3.7
  1004. X * 
  1005. */
  1006. X
  1007. #include "extern.h"
  1008. X
  1009. /*
  1010. ** Return the suffix portion of a filename, assumed to begin with a `.'.
  1011. */
  1012. PUBLIC char *
  1013. Get_suffix(name)
  1014. char *name;
  1015. {
  1016. X   char *suff;
  1017. X
  1018. X   if(name == NIL(char)  || (suff = strrchr(name, '.')) == NIL(char))
  1019. X      suff = ".NULL";
  1020. X
  1021. X   return (suff);
  1022. }
  1023. X
  1024. X
  1025. X
  1026. /*
  1027. ** Take dir and name, and return a path which has dir as the directory
  1028. ** and name afterwards.
  1029. **
  1030. ** N.B. Assumes that the dir separator string is in DirSepStr.
  1031. **      Return path is built in a static buffer, if you need to use it
  1032. **      again you must _strdup the result returned by Build_path.
  1033. */
  1034. PUBLIC char *
  1035. Build_path(dir, name)
  1036. char *dir;
  1037. char *name;
  1038. {
  1039. X   register char *p;
  1040. X   register char *q;
  1041. X   static char     *path  = NIL(char);
  1042. X   static unsigned buflen = 0;
  1043. X   int  plen = 0;
  1044. X   int  dlen = 0;
  1045. X   int  len;
  1046. X
  1047. X   if( dir  != NIL(char) ) dlen = strlen( dir  );
  1048. X   if( name != NIL(char) ) plen = strlen( name );
  1049. X   len = plen+dlen+strlen(DirSepStr)+1;
  1050. X
  1051. X   if( len > buflen ) {
  1052. X      buflen = (len+16) & ~0xf;        /* buf is always multiple of 16 */
  1053. X
  1054. X      if( path == NIL(char) )
  1055. X         path = MALLOC( buflen, char );
  1056. X      else
  1057. X         path = realloc( path, (unsigned) (buflen*sizeof(char)) );
  1058. X   }
  1059. X   
  1060. X   *path = '\0';
  1061. X
  1062. X   if( dlen ) {
  1063. X      strcpy( path, dir );
  1064. X      if( *path && strchr(DirBrkStr, dir[dlen-1]) == NIL(char) )
  1065. X     strcat( path, DirSepStr );
  1066. X   }
  1067. X   strcat( path, name );
  1068. X
  1069. X   q=path;
  1070. X   while( *q ) {
  1071. X      char *t;
  1072. X
  1073. X      p=_strpbrk(q,DirBrkStr);
  1074. X      t=_strpbrk(p+1,DirBrkStr);
  1075. X      if( !*p || !*t ) break;
  1076. X
  1077. X      if(    !(p-q == 2 && strncmp(q,"..",2) == 0)
  1078. X          && t-p-1 == 2 && strncmp(p+1,"..",2) == 0 ) {
  1079. X     t = _strspn(t,DirBrkStr);
  1080. X     strcpy(q,t);
  1081. X      }
  1082. X      else
  1083. X     q = p+1;
  1084. X   }
  1085. X
  1086. X   return( path );
  1087. }
  1088. SHAR_EOF
  1089. chmod 0640 dmake/path.c ||
  1090. echo 'restore of dmake/path.c failed'
  1091. Wc_c="`wc -c < 'dmake/path.c'`"
  1092. test 3063 -eq "$Wc_c" ||
  1093.     echo 'dmake/path.c: original size 3063, current size' "$Wc_c"
  1094. rm -f _shar_wnt_.tmp
  1095. fi
  1096. # ============= dmake/percent.c ==============
  1097. if test -f 'dmake/percent.c' -a X"$1" != X"-c"; then
  1098.     echo 'x - skipping dmake/percent.c (File already exists)'
  1099.     rm -f _shar_wnt_.tmp
  1100. else
  1101. > _shar_wnt_.tmp
  1102. sed 's/^X//' << 'SHAR_EOF' > 'dmake/percent.c' &&
  1103. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/percent.c,v 1.1 91/05/06 15:23:24 dvadura Exp $
  1104. -- SYNOPSIS -- handle building or %-rule meta-target nfa.
  1105. -- 
  1106. -- DESCRIPTION
  1107. --    Builds the NFA used by dmake to match targets against %-meta
  1108. --    rule constructs.  The NFA is built as a set of DFA's.
  1109. -- 
  1110. -- AUTHOR
  1111. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1112. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1113. --
  1114. -- COPYRIGHT
  1115. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1116. -- 
  1117. --      This program is free software; you can redistribute it and/or
  1118. --      modify it under the terms of the GNU General Public License
  1119. --      (version 1), as published by the Free Software Foundation, and
  1120. --      found in the file 'LICENSE' included with this distribution.
  1121. -- 
  1122. --      This program is distributed in the hope that it will be useful,
  1123. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1124. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1125. --      GNU General Public License for more details.
  1126. -- 
  1127. --      You should have received a copy of the GNU General Public License
  1128. --      along with this program;  if not, write to the Free Software
  1129. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1130. --
  1131. -- LOG
  1132. --     $Log:    percent.c,v $
  1133. X * Revision 1.1  91/05/06  15:23:24  dvadura
  1134. X * dmake Release Version 3.7
  1135. X * 
  1136. */
  1137. X
  1138. #include "extern.h"
  1139. X
  1140. static DFAPTR _build_dfa ANSI((char *));
  1141. static char   _shift_dfa ANSI((DFAPTR, char *));
  1142. X
  1143. X
  1144. #define NO_ACTION    0
  1145. #define START_PERCENT    1
  1146. #define END_PERCENT    2
  1147. #define ACCEPT        4
  1148. #define FAIL           -1
  1149. X
  1150. static  NFAPTR _nfa = NIL( NFA );
  1151. X
  1152. X
  1153. PUBLIC DFALINKPTR
  1154. Match_dfa( buf )/*
  1155. ==================
  1156. X   This routines runs all DFA's in parrallel and selects the one that best
  1157. X   matches the string.  If no match then it returns NIL( DFA ) */
  1158. char *buf;
  1159. {
  1160. X   register NFAPTR nfa;
  1161. X   int         adv;
  1162. X   DFALINKPTR       dfa_list = NIL(DFALINK);
  1163. X
  1164. X   DB_ENTER( "Match_dfa" );
  1165. X   DB_PRINT( "dfa", ("Matching %s", buf) );
  1166. X
  1167. X   /* Run each of the DFA's on the input string in parallel, we terminate
  1168. X    * when all DFA's have either failed or ACCEPTED, if more than one DFA
  1169. X    * accepts we build a list of all accepting DFA's sorted on states with
  1170. X    * those matching in a higher numbered state heading the list. */
  1171. X
  1172. X   do {
  1173. X      adv = FALSE;
  1174. X
  1175. X      for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next )
  1176. X     if( nfa->status != (char) FAIL && nfa->status != (char) ACCEPT ) {
  1177. X        adv++;
  1178. X        nfa->status = _shift_dfa( nfa->dfa, buf );
  1179. X
  1180. X        /* Construct the list of matching DFA's */
  1181. X        if( nfa->status == (char) ACCEPT ) {
  1182. X           DFALINKPTR dl;
  1183. X
  1184. X           TALLOC( dl, 1, DFALINK );
  1185. X           dl->dl_meta  = nfa->dfa->node;
  1186. X           dl->dl_per   = _substr( nfa->dfa->pstart, nfa->dfa->pend );
  1187. X           dl->dl_state = nfa->dfa->states - nfa->dfa->c_state;
  1188. X
  1189. X           if( dfa_list == NIL(DFALINK) )
  1190. X              dfa_list = dl;
  1191. X           else {
  1192. X          DFALINKPTR tdli = dfa_list;
  1193. X          DFALINKPTR tdlp = NIL(DFALINK);
  1194. X
  1195. X          for( ; tdli != NIL(DFALINK); tdli = tdli->dl_next ) {
  1196. X             if( dl->dl_state >= tdli->dl_state )
  1197. X            break;
  1198. X             tdlp = tdli;
  1199. X          }
  1200. X
  1201. X          if( tdli != NIL(DFALINK) ) {
  1202. X             tdli->dl_prev = dl;
  1203. X             dl->dl_next   = tdli;
  1204. X          }
  1205. X
  1206. X          if( tdlp != NIL(DFALINK) ) {
  1207. X             tdlp->dl_next = dl;
  1208. X             dl->dl_prev   = tdlp;
  1209. X          }
  1210. X          else
  1211. X             dfa_list = dl;
  1212. X           }
  1213. X
  1214. X           DB_PRINT( "dfa", ("Matched [%s]", dl->dl_meta->CE_NAME) );
  1215. X        }
  1216. X     }
  1217. X
  1218. X      buf++;
  1219. X   }
  1220. X   while ( adv );
  1221. X
  1222. X   for( nfa = _nfa; nfa != NIL( NFA ); nfa = nfa->next ) {
  1223. X      nfa->status = 0;
  1224. X      nfa->dfa->c_state = nfa->dfa->states;
  1225. X   }
  1226. X
  1227. X   DB_RETURN( dfa_list );
  1228. }
  1229. X
  1230. X
  1231. PUBLIC void
  1232. Check_circle_dfa()/*
  1233. ====================
  1234. X   This function is called to test for circularities in the DFA lists
  1235. X   constructed from %-meta targets. */
  1236. {
  1237. X   register NFAPTR nfa;
  1238. X
  1239. X   for( nfa = _nfa; nfa != NIL(NFA); nfa = nfa->next )
  1240. X      if( Test_circle( nfa->dfa->node, FALSE ) )
  1241. X     Fatal( "Detected circular dependency in inference graph at [%s]",
  1242. X        nfa->dfa->node->CE_NAME );
  1243. }
  1244. X
  1245. X
  1246. PUBLIC void
  1247. Add_nfa( name )/*
  1248. =================
  1249. X   Given name, build a DFA and add it to the NFA.  The NFA is maintained as
  1250. X   a singly linked list of DFA's. */
  1251. char *name;
  1252. {
  1253. X   NFAPTR nfa;
  1254. X
  1255. X   TALLOC(nfa, 1, NFA);
  1256. X   nfa->dfa = _build_dfa(name);
  1257. X
  1258. X   if( _nfa != NIL(NFA) ) nfa->next = _nfa;
  1259. X
  1260. X   _nfa = nfa;
  1261. }
  1262. X
  1263. X
  1264. static DFAPTR
  1265. _build_dfa( name )/*
  1266. ====================
  1267. X   Construct a dfa for the passed in cell name.  The routine returns a struct
  1268. X   that represents a finite state machine that can recognize a regular
  1269. X   expression with exactly one '%' sign in it.  The '%' symbol is used as a
  1270. X   wildcard character that will match anything except the character that
  1271. X   immediately follows it or NUL.
  1272. X
  1273. X   The Construction of DFA's is well know and can be found in Hopcroft and
  1274. X   Ullman or any other book discussing formal language theory.
  1275. X   A more practical treatise can be found in Compilers, Aho, Sethi and Ullman.
  1276. */
  1277. char *name;
  1278. {
  1279. X   DFAPTR   dfa;
  1280. X   int      nstates;
  1281. X   register STATEPTR sp;
  1282. X   STATEPTR per_state = NIL(STATE);
  1283. X   int      pcount=0;
  1284. X   int      end_percent=FALSE;
  1285. X
  1286. X   nstates = strlen(name)+2;
  1287. X
  1288. X   /* Allocate a DFA node and the right number of states. */
  1289. X   TALLOC(dfa, 1, DFA);
  1290. X   TALLOC(sp=dfa->c_state=dfa->states, nstates, STATE);
  1291. X   dfa->node = Def_cell( name );
  1292. X
  1293. X   /* Now construct the state table for the DFA */
  1294. X   do {
  1295. X      if( *name == '%' ) {
  1296. X     if( pcount++ > 0 )
  1297. X        Error( "Only one %% allowed within a %%-meta target" );
  1298. X
  1299. X     sp->symbol   = 0;
  1300. X     sp->action   = START_PERCENT;
  1301. X     sp->no_match = sp->match = per_state = sp+1;
  1302. X     end_percent  = TRUE;
  1303. X      }
  1304. X      else {
  1305. X     sp->symbol   = *name;
  1306. X     sp->no_match = per_state;
  1307. X
  1308. X     if( *name == '\0' ) {
  1309. X        sp->action = ACCEPT;
  1310. X        sp->match  = dfa->states;
  1311. X     }
  1312. X     else {
  1313. X        sp->action = NO_ACTION;
  1314. X        sp->match  = sp+1;
  1315. X     }
  1316. X
  1317. X     if( end_percent ) {
  1318. X        sp->action |= END_PERCENT;
  1319. X        end_percent = FALSE;
  1320. X     }
  1321. X      }
  1322. X      
  1323. X      sp++; 
  1324. X   }
  1325. X   while( *name++ );
  1326. X
  1327. X   return(dfa);
  1328. }
  1329. X
  1330. X
  1331. static char
  1332. _shift_dfa( dfa, data )/*
  1333. =========================
  1334. X   Take a given dfa and advance it based on the current state, the shift
  1335. X   action in that state, and the current data value. */
  1336. DFAPTR dfa;
  1337. char   *data;
  1338. {
  1339. X   register STATEPTR sp = dfa->c_state;
  1340. X   char c = *data;
  1341. X
  1342. X   /* Check if it is a START_PERCENT action if so then we need to save
  1343. X    * a pointer to the start of the string and advance to the next state. */
  1344. X   if( sp->action & START_PERCENT ) {
  1345. X      dfa->pstart = data;
  1346. X      sp++;
  1347. X   }
  1348. X
  1349. X   /* Now check if the current char matches the character expected in the
  1350. X    * current state.  If it does then perform the specified action, otherwise
  1351. X    * either shift it or fail.  We fail if the next state on no-match is
  1352. X    * NIL. */
  1353. X   if( sp->symbol == c ) {
  1354. X      if( sp->action & END_PERCENT ) dfa->pend = data;
  1355. X      if( sp->action & ACCEPT ) return(ACCEPT);
  1356. X      dfa->c_state = sp->match;
  1357. X   }
  1358. X   else if( (dfa->c_state = sp->no_match) == NIL(STATE) || !c )
  1359. X      return(FAIL);
  1360. X
  1361. X   return(NO_ACTION);
  1362. }
  1363. SHAR_EOF
  1364. chmod 0640 dmake/percent.c ||
  1365. echo 'restore of dmake/percent.c failed'
  1366. Wc_c="`wc -c < 'dmake/percent.c'`"
  1367. test 7050 -eq "$Wc_c" ||
  1368.     echo 'dmake/percent.c: original size 7050, current size' "$Wc_c"
  1369. rm -f _shar_wnt_.tmp
  1370. fi
  1371. # ============= dmake/quit.c ==============
  1372. if test -f 'dmake/quit.c' -a X"$1" != X"-c"; then
  1373.     echo 'x - skipping dmake/quit.c (File already exists)'
  1374.     rm -f _shar_wnt_.tmp
  1375. else
  1376. > _shar_wnt_.tmp
  1377. sed 's/^X//' << 'SHAR_EOF' > 'dmake/quit.c' &&
  1378. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/quit.c,v 1.1 91/05/06 15:23:25 dvadura Exp $
  1379. -- SYNOPSIS -- end the dmake session.
  1380. -- 
  1381. -- DESCRIPTION
  1382. --     Handles dmake termination.
  1383. --
  1384. -- AUTHOR
  1385. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  1386. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  1387. --
  1388. -- COPYRIGHT
  1389. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  1390. -- 
  1391. --      This program is free software; you can redistribute it and/or
  1392. --      modify it under the terms of the GNU General Public License
  1393. --      (version 1), as published by the Free Software Foundation, and
  1394. --      found in the file 'LICENSE' included with this distribution.
  1395. -- 
  1396. --      This program is distributed in the hope that it will be useful,
  1397. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  1398. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1399. --      GNU General Public License for more details.
  1400. -- 
  1401. --      You should have received a copy of the GNU General Public License
  1402. --      along with this program;  if not, write to the Free Software
  1403. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1404. --
  1405. -- LOG
  1406. --     $Log:    quit.c,v $
  1407. X * Revision 1.1  91/05/06  15:23:25  dvadura
  1408. X * dmake Release Version 3.7
  1409. X * 
  1410. */
  1411. X
  1412. #include "extern.h"
  1413. X
  1414. static    void    _handle_quit ANSI((char*));
  1415. static    int    _dont_quit = 0;
  1416. X
  1417. X
  1418. PUBLIC void
  1419. Quit()/*
  1420. ======== Error or quit */
  1421. {
  1422. X   if( _dont_quit ) return;
  1423. SHAR_EOF
  1424. true || echo 'restore of dmake/quit.c failed'
  1425. fi
  1426. echo 'End of part 27, continue with part 28'
  1427. echo 28 > _shar_seq_.tmp
  1428. exit 0
  1429.  
  1430. exit 0 # Just in case...
  1431. -- 
  1432. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1433. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1434. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1435. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1436.